﻿using AppEvents;
using MebApp.Launcher.Helpers;
using MebApp.Launcher.Model;
using Newtonsoft.Json;
using MebAppLib;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using AppEvents.JsonModel;
using TinyUtil;

namespace MebApp.Launcher
{
    public class AppInstaller
    {
        static List<InstalledApp> InstalledApps;
        static string AppBaseDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../apps");
        static string file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../apps", "applist.json");
        static AppInstaller()
        {
            AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += CurrentDomain_ReflectionOnlyAssemblyResolve;
            try
            {
                InstalledApps = JsonConvert.DeserializeObject<List<InstalledApp>>(File.ReadAllText(file)) ?? new List<InstalledApp>();
            }
            catch (Exception ex)
            {
                InstalledApps = new List<InstalledApp>();
            }
        }

        private static Assembly CurrentDomain_ReflectionOnlyAssemblyResolve(object sender, ResolveEventArgs args)
        {
            try
            {
                return Assembly.ReflectionOnlyLoad(args.Name);
            }
            catch
            {
                return null;
            }
        }

        public static List<InstalledApp> GetInstalledApps()
        {
            lock (InstalledApps)
            {
                return InstalledApps.ToList();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id">-1表示未安装</param>
        /// <returns></returns>
        public static int GetInstalledVersion(Guid id)
        {
            lock (InstalledApps)
            {
                var item = InstalledApps.Find(x => x.ID == id);
                if (item == null)
                    return -1;
                return item.Version;
            }
        }

        public static bool IsAppInstalled(Guid id, int version)
        {
            lock (InstalledApps)
            {
                var item = InstalledApps.Find(x => x.ID == id && x.Version == version);
                return item != null;
            }
        }

        public static InstalledApp GetInstalledApp(Guid id)
        {
            lock (InstalledApps)
            {
                return InstalledApps.Find(x => x.ID == id);
            }
        }

        public static AppRuntime GetLoadOption(Guid id)
        {
            lock (InstalledApps)
            {
                var item = InstalledApps.Find(x => x.ID == id);
                if (item != null)
                {
                    return item.RtmOption;
                }
                throw new Exception("App未安装或已损坏，请重新安装！");
            }
        }
        public static void RemoveFromAppList(Guid id)
        {
            lock (InstalledApps)
            {
                var item = InstalledApps.Find(x => x.ID == id);
                if (item != null)
                {
                    if (Directory.Exists(item.Location))
                    {
                        var files = Directory.EnumerateFiles(item.Location);
                        foreach (var file in files)
                        {
                            if (!Path.GetFileName(file).Equals("app.zip", StringComparison.OrdinalIgnoreCase))
                            {
                                try
                                {
                                    File.Delete(file);
                                }
                                catch
                                {
                                    //删不掉的就算了
                                }
                            }
                        }

                    }
                    InstalledApps.Remove(item);
                }
                var text = JsonConvert.SerializeObject(InstalledApps, Formatting.Indented);
                try
                {
                    File.WriteAllText(file, text);
                }
                catch { }
            }
        }

        public static void AddInstalled(AppJson app, string location)
        {
            lock (InstalledApps)
            {
                var opt = GetAppRuntime(location, app.ID);
                opt.AppID = app.ID.ToString();
                opt.AppName = app.Name;
                opt.AppVersion = app.Version;
                var installed = new InstalledApp
                {
                    Location = location,
                    Version = app.Version,
                    ID = app.ID,
                    InstallTime = DateTime.Now,
                    Name = app.Name,
                    RtmOption = opt
                };
                var prevApp = InstalledApps.Find(x => x.ID == app.ID);
                if (prevApp != null)
                {
                    InstalledApps.Remove(prevApp);
                }
                InstalledApps.Add(installed);
                var text = JsonConvert.SerializeObject(InstalledApps, Formatting.Indented);
                try
                {
                    File.WriteAllText(file, text);
                }
                catch { }
            }
        }

        private static AppRuntime GetAppRuntime(string path, Guid appId)
        {
            var appInfo = JsonFile.Read<AppInfo>(Path.Combine(path, "app.json"));
            var appRtm = new AppRuntime();
            appRtm.StartupFile = Path.Combine(path, appInfo.StartupFile);
            appRtm.StartupPath = path;
            appRtm.StartupConfigFile = appRtm.StartupFile + ".config";
            return appRtm;
        }
    }
}
